"""LDAP models."""

import django.core.files

from django.conf import settings
from oldap.model import Model
from oldap.reference import Reference

class Domain(Model):

    base_dn = settings.LDAP_BASE_DN_DOMAIN
    objectClass = ('hcpDomain',)
    rdn_attributes = ('hcpDomainName',)

    pretty_name = 'domain'

class Person(Model):

    base_dn = settings.LDAP_BASE_DN_PERSON
    objectClass = ('hcpPerson', 'posixAccount')
    rdn_attributes = ('uid',)

    pretty_name = 'user'

class Group(Model):

    base_dn = settings.LDAP_BASE_DN_GROUP
    objectClass = ('posixGroup',)
    rdn_attributes = ('cn',)
    memberUid = Reference(Person, 'uid')

    pretty_name = 'group'

    @classmethod
    def next_gidNumber(cls):
        try:
            max_id = cls.objects.order_by('-gidNumber')[0].gidNumber
        except IndexError:
            max_id = settings.POSIX_MIN_GID
        return str(int(max_id)+1)

class Host(Model):

    base_dn = settings.LDAP_BASE_DN_HOST
    objectClass = ('hcpHost', 'ipHost')
    rdn_attributes = ('cn',)

    pretty_name = 'host'

class MailAlias(Model):

    base_dn = settings.LDAP_BASE_DN_MAIL_ALIAS
    objectClass = ('hcpMailAlias',)
    rdn_attributes = ('mail',)

    pretty_name = 'mail alias'

class Organization(Model):

    base_dn = settings.LDAP_BASE_DN
    objectClass = ('organization', 'dcObject')
    rdn_attributes = ()

class OrganizationalUnit(Model):

    base_dn = settings.LDAP_BASE_DN
    objectClass = ('organizationalUnit',)
    rdn_attributes = ('ou',)


def update_model_from_post(model, data, field_names):

    for attr_name in field_names:
        values = data[attr_name]
        if not isinstance(values, (list, tuple)):
            values = [values]
        new_values = []
        for value in values:
            if isinstance(value, django.core.files.File):
                value = value.read()
            elif isinstance(value, unicode):
                value = value.encode('utf-8')
            elif isinstance(value, (list, tuple)):
                # These are special (combined), ignore them.
                break
            else:
                value = str(value)
            if not value:
                continue
            new_values.append(value)
        if new_values:
            setattr(model, attr_name, new_values)
        else:
            # Remove any attributes that didn't get any values set.
            try:
                delattr(model, attr_name)
            except AttributeError:
                pass
        # XXX: Does empty string ever show up?

def set_auto_manual_id(attr_name, form, model, model_class, min_value):
    field_type = form.cleaned_data[attr_name][0]
    if field_type == 'AUTO':
        try:
            # XXX: Think of a better way to do this.
            max_obj = model_class.objects.order_by('-'+attr_name)[0]
            max_id = getattr(max_obj, attr_name)
        except IndexError:
            max_id = min_value

        new_id = str(int(max_id)+1)
    elif field_type == 'MANUAL':
        new_id = str(form.cleaned_data[attr_name][1])
    else:
        raise AssertionError(field_type)

    setattr(model, attr_name, new_id)
    return new_id
